<template>
  <div class="app-container">
    <div class="test">
      需求：目标可以自定义背景图，可以自定义内部输入框个数，位置以拖拽的形式移动，可以自定义印章
    </div>
    <div>
      <div>
        <formForm :formValue.sync="formValue" ref="formForm"></formForm>
      </div>
      <div>
        <div ref="canvas"
             :id="parentId"
             class="preview-class" style="position: relative;">
          <el-popover
            placement="top-start"
            title="标题"
            width="200"
            v-for="(item, index) in formValue"
            :key="index"
            trigger="hover"
            content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。">
            <vue-draggable-resizable
              slot="reference"
              class-name="my-class"
              :resizable="true"
              :w="item.divWidth"
              :h="item.divHeight"
              :z-index="item.ZLocation"
              @dragging="dragging(arguments, item, index)"
              @dragstop="dragstop(arguments, item, index)"
              :parent="'#'+parentId">
              <p v-if="item.type == 'text'" style="word-break:break-all;" :style="item.style">{{item.value}}</p>
              <img v-if="item.type == 'img'" style="width:100%;height: 100%;" :src="item.src">
            </vue-draggable-resizable>
          </el-popover>
        </div>
      </div>
      <div>
        <div>
          <button @click="toImg">生成图片</button>
          <button @click="downImg">下载图片</button>
        </div>
        <img :src="img" v-if="img" />
      </div>
    </div>
  </div>
</template>

<script>
import vueDraggableResizable from 'vue-draggable-resizable-gorkys';
import 'vue-draggable-resizable-gorkys/dist/VueDraggableResizable.css';
import html2canvas from 'html2canvas';
import formForm from '@/views/CertificateGenerator/formForm/index.vue';
import {createUniqueString} from "@localModules/ZhiXinLib/utils/index";
export default {
  mixins: [],
  components: {
    formForm,
    vueDraggableResizable,
  },
  props: {},
  data() {
    return {
      parentId: createUniqueString(),
      formData: {
        nameDom: '',
        dateDom: '',
        detailDom: '',
        orgsDom: '',
      },
      formValue: [],
      formArr: [],
      certificate: null,
      timeoutId: null,
      img: '',
      width: 0,
      height: 0,
      x: 0,
      y: 0,
    };
  },
  computed: {},
  watch: {
    formValue: {
      handler(v, oldV) {
        this.checkPreview();
      },
      deep: true,
    },
  },

  mounted() {},
  created() {
    this.sample();
  },
  methods: {
    dragging(e, item, index) {
      this.$set(this.formValue[index], 'disabled', true);
    },
    dragstop(e, item, index) {
      this.$set(this.formValue[index], 'disabled', false);
      this.$set(this.formValue[index], 'YLocation', e[0]);
      this.$set(this.formValue[index], 'XLocation', e[1]);
    },
    downImg() {
      if (!this.img) {
        this.$message.warning('未生成文件');
      }
      this.ToDownload(this.img, '测试文件.png');
    },
    getBase64(imgUrl, index) {
      let that = this;
      window.URL = window.URL || window.webkitURL;
      var xhr = new XMLHttpRequest();
      xhr.open('get', imgUrl, true);
      // 至关重要
      xhr.responseType = 'blob';
      let base64 = '';
      xhr.onload = function () {
        if (this.status == 200) {
          //得到一个blob对象
          var blob = this.response;
          // 至关重要
          let oFileReader = new FileReader();
          oFileReader.onloadend = function (e) {
            // 此处拿到的已经是 base64的图片了
            base64 = e.target.result;
            that.$set(that.formArr[0], 'src', base64);
            that.checkPreview();
          };
          oFileReader.readAsDataURL(blob);
          //====为了在页面显示图片，可以删除====
          // var img = document.createElement('img');
          // img.onload = function (e) {
          //   window.URL.revokeObjectURL(img.src); // 清除释放
          // };
          // let src = window.URL.createObjectURL(blob);
          // img.src = src;
          //document.getElementById("container1").appendChild(img);
          //====为了在页面显示图片，可以删除====
        }
      };
      xhr.send();
      return base64;
    },
    formate(v) {
      v.forEach((j, index) => {
        if (j.type == 'img') {
          if (
            j.value &&
            !j.src &&
            (j.value.indexOf('http') > -1 || j.value.indexOf('https') > -1)
          ) {
            console.log(this.getBase64(j.value), 'this.getBase64(j.value)');
            j.src = this.getBase64(j.value, index);
          }
        }
      });
      this.formArr = v;
    },
    toImg() {
      html2canvas(this.$refs.canvas, {}).then((canvas) => {
        this.img = canvas.toDataURL('image/png');
      });
    },
    ToDownload(url, name) {
      let eleLink = document.createElement('a');
      eleLink.style.display = 'none';
      // 图片转base64地址
      eleLink.href = url;
      eleLink.download = name;
      // 触发点击
      document.body.appendChild(eleLink);
      eleLink.click();
      // 然后移除
      document.body.removeChild(eleLink);
      eleLink = null;
      return true;
    },
    checkPreview() {
      let name = this.formData.nameDom;
      let detail = this.formData.detailDom;
      let orgs = this.formData.orgsDom;
      let date = this.formData.dateDom;
      clearTimeout(this.timeoutId);
      // 允许渲染
      if (name.trim() && detail.trim() && orgs.trim() && date.trim()) {
        this.timeoutId = setTimeout(() => {
          // this.preview(name, detail, orgs, date);
        }, 1000);
      }
    },
    sample() {
      this.formData.nameDom = `林一怂儿`;
      this.formData.detailDom =
        '在2021年全国优秀文章中，你以优秀的错别字数量，以及非常离谱的Bug，遥遥领先。特发此证，以资鼓励。';
      this.formData.orgsDom = `哈哈哈哈\n嘿嘿嘿`;
      this.formData.dateDom = '2021年12月';
      this.checkPreview();
    },

    preview(name, detail, orgs, date) {
      let c = document.getElementById('preview');
      let ctx = c.getContext('2d');
      // 证书背景
      ctx.drawImage(
        document.getElementsByTagName('img').item(0),
        0,
        0,
        c.clientWidth,
        c.clientHeight
      );
      // 获奖人
      ctx.font = '22px Microsoft YaHei';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'top';
      ctx.fillText(name, 102 + 255 / 2, 183);
      // 冒号
      ctx.textAlign = 'right';
      ctx.fillText(':', 102 + 255, 183);
      // 获奖人底线
      ctx.beginPath();
      ctx.moveTo(102, 220);
      ctx.lineTo(102 + 245, 220);
      ctx.stroke();

      // 获奖成就
      let detailX = 147;
      let detailY = 237;

      ctx.font = '22px Microsoft YaHei';
      ctx.textAlign = 'left';
      ctx.textBaseline = 'top';
      for (let i = 0; i < detail.length; i++) {
        detailX += 32;
        if (detailX > 640) {
          detailX = 115;
          detailY += 32;
        }
        ctx.fillText(detail[i], detailX, detailY);
        if (detail.charCodeAt(i) <= 255) detailX -= 16;
      }

      // 颁发机构
      let orgX = c.clientWidth - 147 - 180;
      let orgY = 356;

      ctx.font = '14px Microsoft YaHei';
      ctx.textAlign = 'left';
      ctx.textBaseline = 'top';
      let orgArr = orgs.split(/\n/).map((o) => o.trim());
      for (let i = 0; i < orgArr.length; i++) {
        ctx.fillText(orgArr[i], orgX, orgY);
        orgY += 30;

        let img = new Image();
        img.src = this.seal(orgArr[i]);
        img.onload = function () {
          ctx.drawImage(img, c.clientWidth - 220 - i * 110, 350, 100, 100);
        };
      }
      // 绘制获奖日期
      ctx.font = '14px Microsoft YaHei';
      ctx.textAlign = 'left';
      ctx.textBaseline = 'top';
      ctx.fillText(date, c.clientWidth - 130 - 153, 450);
    },
    seal(s) {
      // 防止转圈圈
      if (!s) return;
      let c = document.getElementById('seal');
      let ctx = c.getContext('2d');
      ctx.clearRect(0, 0, c.clientWidth, c.clientHeight);
      ctx.fillStyle = 'rgb(196,38,29)';
      ctx.strokeStyle = 'rgb(196,38,29)';
      // 印章的外框
      ctx.beginPath();
      ctx.lineWidth = 4;
      ctx.arc(100, 100, 96, 0, 2 * Math.PI);
      ctx.stroke();
      // 星星的生成
      ctx.beginPath();
      ctx.lineWidth = 1;
      let star_start_x = 76;
      let star_start_y = 88;
      ctx.moveTo(star_start_x, star_start_y);
      ctx.lineTo(star_start_x + 20, star_start_y);
      ctx.lineTo(star_start_x + 20 + 7, star_start_y - 20);
      ctx.lineTo(star_start_x + 20 + 7 + 6, star_start_y);
      ctx.lineTo(star_start_x + 20 + 7 + 6 + 20, star_start_y);
      ctx.lineTo(star_start_x + 20 + 7 + 6 + 20 - 16, star_start_y + 13);
      ctx.lineTo(star_start_x + 20 + 7 + 6 + 20 - 16, star_start_y + 13);
      ctx.lineTo(
        star_start_x + 20 + 7 + 6 + 20 - 16 + 5,
        star_start_y + 13 + 20
      );
      ctx.lineTo(
        star_start_x + 20 + 7 + 6 + 20 - 16 + 5 - 16,
        star_start_y + 20
      );
      ctx.lineTo(
        star_start_x + 20 + 7 + 6 + 20 - 16 + 5 - 16 - 18,
        star_start_y + 13 + 20
      );
      ctx.lineTo(
        star_start_x + 20 + 7 + 6 + 20 - 16 + 5 - 16 - 18 + 6,
        star_start_y + 13
      );
      ctx.closePath();
      ctx.fill();
      // 印章上旋转的文字
      ctx.translate(100, 100);
      ctx.font = '26px Helvetica';
      let angle = (4 * Math.PI) / (3 * (s.length - 1));
      for (var i = 0; i < s.length; i++) {
        let c = s[i];
        if (i == 0) ctx.rotate(0.8 * Math.PI);
        else ctx.rotate(angle);
        ctx.save();
        ctx.translate(70, 0);
        ctx.rotate(Math.PI / 2);
        ctx.fillText(c, 0, 5);
        ctx.restore();
      }
      // 归位
      ctx.rotate(-angle * (s.length - 1));
      ctx.rotate(-0.8 * Math.PI);
      ctx.translate(-100, -100);

      return c.toDataURL();
    },
  },
};
</script>

<style scoped lang="scss">
::v-deep {
  // 取消默认外边框虚线
  .active {
    &::before {
      display: none;
    }
  }
}
.preview-class {
  position: relative;
  display: inline-block;
  width: 700px;
  height: 500px;
  background-image: url('@/assets/certificate-1.jpg');
  background-repeat: no-repeat;
  background-size: 100% 100%;
}

img {
  width: 768px;
}

.name,
.detail,
.date,
.orgs,
.colon {
  position: absolute;
  font-family: 'Microsoft YaHei';
}

.name {
  // top: 183px;
  // left: 102px;
  width: 255px;
  font-size: 27px;
  line-height: 36px;
  background-color: transparent;
  border-bottom-width: 2px;
  border-bottom-color: #999;
  border-top-width: 0;
  border-left-width: 0;
  border-right-width: 0;
  text-align: center;
  outline: none;
}

.colon {
  top: 190px;
  left: calc(107px + 255px);
  font-size: 27px;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: bold;
}

.detail {
  // top: 237px;
  // left: 94px;
  height: 90px;
  width: 559px;
  background-color: transparent;
  resize: none;
  border: none;
  font-size: 22px;
  letter-spacing: 4px;
  outline: none;
  text-indent: 50px;
}

.date {
  // top: 432px;
  // right: 130px;
  font-size: 14px;
  line-height: 36px;
  background-color: transparent;
  border: none;
  outline: none;
}

.orgs {
  top: 356px;
  right: 147px;
  width: 180px;
  background-color: transparent;
  resize: none;
  border: none;
  font-size: 14px;
  outline: none;
  text-align: justify;
  height: 80px;
}
.test {
  position: absolute;
  top: 0;
}
</style>
